package com.whoyx.jiebing.domain.msg.resp;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.whoyx.jiebing.dao.entity.MsgRecordEntity;
import com.whoyx.jiebing.domain.enums.MsgTypeEnum;
import com.whoyx.jiebing.domain.msg.MsgBody;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class MsgDataRespDtoV2 {
    @JsonProperty("ID")
    private String id;

    /**
     * 发送方uid
     */
    private String from;

    /**
     * 发送方头像
     */
    private String avatar;

    /**
     * 接收方uid
     */
    private String to;

    /**
     * 输入输出
     */
    private String flow;

    /**
     * 类型
     * @see MsgTypeEnum
     */
    private String type;

    /**
     * 消息时间
     */
    private Long time;

    private String timeFormatter;

    /**
     * 消息内容
     */
    private Object payload;

    private Boolean isRevoked;

    /**
     * 自定义消息
     */
    private String cloudCustomData;


    public static MsgDataRespDtoV2 buildWithEntity(MsgRecordEntity entity, String representUid, String fromAvatar) {
        String msgTime;
        if (LocalDate.now().atStartOfDay().isBefore(entity.getMsgTime())
                || LocalDate.now().atStartOfDay().equals(entity.getMsgTime())) {
            if (LocalDate.now().atStartOfDay().plusHours(12).isAfter(entity.getMsgTime())) {
                msgTime = LocalDateTimeUtil.format(entity.getMsgTime(), "HH:mm");
            } else {
                msgTime = LocalDateTimeUtil.format(entity.getMsgTime(), "HH:mm");
            }
        } else if (LocalDate.now().minusDays(1).atStartOfDay().isBefore(entity.getMsgTime())
                || LocalDate.now().minusDays(1).atStartOfDay().equals(entity.getMsgTime())) {
            msgTime = "昨天";
        } else {
            msgTime = LocalDateTimeUtil.format(entity.getMsgTime(), DatePattern.NORM_DATE_PATTERN);
        }


        String flow = representUid.equals(entity.getFromUid()) ? "out" : "in";
        List<MsgBody> msgBodyList = JSONUtil.toList(entity.getMsgBody(), MsgBody.class);
        MsgBody msgBody = msgBodyList.get(0);
        JSONObject jsonObject = JSONUtil.parseObj(msgBody.getMsgContent());
        Map<String, Object> msgBodyMap = new HashMap<>();
        if (msgBody.getMsgType().equals(MsgTypeEnum.TIMTextElem.getName())) {
            msgBodyMap.put("text", jsonObject.get("Text"));
        } else if (msgBody.getMsgType().equals(MsgTypeEnum.TIMSoundElem.getName())) {
            msgBodyMap.put("size", jsonObject.get("Size"));
            msgBodyMap.put("second", jsonObject.get("Second"));
            msgBodyMap.put("downloadFlag", jsonObject.get("Download_Flag"));
            msgBodyMap.put("uuid", jsonObject.get("UUID"));
            msgBodyMap.put("url", jsonObject.get("Url"));
        } else if (msgBody.getMsgType().equals(MsgTypeEnum.TIMImageElem.getName())) {
            msgBodyMap.put("imageFormat", jsonObject.get("ImageFormat"));
            msgBodyMap.put("uuid", jsonObject.get("UUID"));
            List<Object> imageInfoArray = jsonObject.getBeanList("ImageInfoArray", Object.class);
            List<Map<String, Object>> imageInfoMapArray = imageInfoArray.stream().map(i -> {
                JSONObject imageInfoJsonObject = JSONUtil.parseObj(i);
                int sizeType = (int) (imageInfoJsonObject.get("Type"));
                int type = 0;
                if (sizeType == 1) {
                    type = 0;
                } else if (sizeType == 2) {
                    type = 2;
                } else if (sizeType == 3) {
                    type = 1;
                }
                Map<String, Object> imageInfoMap = new HashMap<>();
                imageInfoMap.put("height", imageInfoJsonObject.get("Height"));
                imageInfoMap.put("width", imageInfoJsonObject.get("Width"));
                imageInfoMap.put("size", imageInfoJsonObject.get("Size"));
                imageInfoMap.put("sizeType",  imageInfoJsonObject.get("Type"));
                imageInfoMap.put("type",  type);
                imageInfoMap.put("imageUrl", imageInfoJsonObject.get("URL"));
                return imageInfoMap;
            }).collect(Collectors.toList());
            msgBodyMap.put("imageInfoArray", imageInfoMapArray);
        } else if (msgBody.getMsgType().equals(MsgTypeEnum.TIMCustomElem.getName())) {
            msgBodyMap.put("data", jsonObject.get("Data"));
            msgBodyMap.put("description", jsonObject.get("Desc"));
            msgBodyMap.put("extension", jsonObject.get("Ext"));
        } else if (msgBody.getMsgType().equals(MsgTypeEnum.TIMVideoFileElem.getName())) {
            msgBodyMap.put("videoFormat",jsonObject.get("VideoFormat"));
            msgBodyMap.put("videoSecond",jsonObject.get("VideoSecond"));
            msgBodyMap.put("videoSize",jsonObject.get("VideoSize"));
            msgBodyMap.put("videoUrl",jsonObject.get("VideoUrl"));
            msgBodyMap.put("videoUUID",jsonObject.get("VideoUUID"));
            msgBodyMap.put("snapshotWidth",jsonObject.get("ThumbWidth"));
            msgBodyMap.put("snapshotHeight",jsonObject.get("ThumbHeight"));
            msgBodyMap.put("snapshotUrl",jsonObject.get("ThumbUrl"));
            msgBodyMap.put("thumbWidth",jsonObject.get("ThumbWidth"));
            msgBodyMap.put("thumbHeight",jsonObject.get("ThumbHeight"));
            msgBodyMap.put("thumbUrl",jsonObject.get("ThumbUrl"));
        }


        return MsgDataRespDtoV2.builder()
                .avatar(fromAvatar)
                .id(entity.getMsgKey())
                .time(entity.getTimeStamp())
                .from(entity.getFromUid())
                .to(entity.getToUid())
                .flow(flow)
                .timeFormatter(msgTime)
                .type(msgBody.getMsgType())
                .payload(msgBodyMap)
                .cloudCustomData(entity.getCloudCustomData())
                .isRevoked(entity.getDeleted() != 0)
                .build();
    }

//    public static Map<String, Object> lowercase(Object obj) {
//        Class<?> clazz = obj.getClass();
//        Field[] fields = clazz.getDeclaredFields();
//        Map<String, Object> map = new HashMap<>();
//        for (Field field : fields) {
//            try {
//                field.setAccessible(true);
//                String name = field.getName();
//                String key = toLowerCaseFirstOne(name);
//                map.put(key, field.get(name));
//            } catch (Exception e) {
//                log.error(e.getMessage());
//            }
//        }
//        return map;
//
//    }
//
//    public static String toLowerCaseFirstOne(String s) {
//        if (Character.isLowerCase(s.charAt(0)))
//            return s;
//        else
//            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
//    }
}
